package cmd

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"io"
	"os"
	"strings"

	"gitee.com/qianyucc/secure-tool/util"
	"github.com/spf13/cobra"
)

const (
	//HASH_BLOCK_SIZE 每次读取文件的一部分进行md5计算
	HASH_BLOCK_SIZE = 1024 * 10
)

// md5Cmd 计算MD5
var md5Cmd = &cobra.Command{
	Use:   "md5",
	Short: "Get the hash of string or file through MD5 algorithm",
	Long:  `Get the hash of string or file through MD5 algorithm`,
	Run: func(cmd *cobra.Command, args []string) {
		var res string
		var err error
		if InputFile == "" {
			var text string
			if text = util.ReadTextFromClipboard(); text == "" && len(args) == 0 {
				fmt.Println("invalid parameter numbers, please enter the string you want to get the hash")
				return
			}
			if len(args) > 0 {
				text = args[0]
			}
			res = ComputeStringWithMd5(text)
		} else {
			if res, err = ComputeFileWithMd5(InputFile); err != nil {
				fmt.Println(err)
				return
			}
		}
		if IsUpperCase {
			res = strings.ToUpper(res)
		}
		util.PrintAndCopyTextToClipboardIgnoreError(res)
	},
}

// ComputeStringWithMd5 计算字符串的 MD5
func ComputeStringWithMd5(text string) (res string) {
	data := []byte(text)
	sum := md5.Sum(data)
	return hex.EncodeToString(sum[:])
}

// ComputeFileWithMd5 计算文件的 MD5
func ComputeFileWithMd5(inputFilePath string) (res string, err error) {
	if inputFilePath == "" {
		return "", fmt.Errorf("invalid parameter numbers, please enter the file name you want to get the hash")
	}
	var fp *os.File
	if fp, err = os.Open(inputFilePath); err != nil {
		return "", err
	}
	defer fp.Close()
	hash := md5.New()
	buf := make([]byte, HASH_BLOCK_SIZE)
	if _, err := io.CopyBuffer(hash, fp, buf); err != nil {
		return "", err
	}
	r := hex.EncodeToString(hash.Sum(nil))
	return r, nil
}

func init() {
	rootCmd.AddCommand(md5Cmd)

	md5Cmd.Flags().StringVarP(&InputFile, "file", "f", "", "The name of the file you are going to hash")
	md5Cmd.Flags().BoolVarP(&IsUpperCase, "upperCase", "u", false, "Indicates whether the result is upper case")
}
